Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Commit 4bd787ccd70a459a02eececca3f942f0e64ec4ce


Parents : cf5bbb3
Author : Ivan <e46112d44649266d71fe2193e00a4710>
Signature : T66BB85Valid, signed by author
Date : 2026-07-25T16:29:02-05:00

feat: make AppContainer sandboxing opt-in for Windows for now

Changes
Diff

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1820bf25..d8e4618f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
- **Windows desktop**: Frozen backends start again instead of failing when aiohttp imports the standard library email package.
- **Desktop packaging**: Only the correct LXST filterlib binary ships per platform so integrity checks match the installer. CI runs a frozen import smoke test before release.
+- **Windows desktop**: AppContainer sandboxing is opt-in (set MESHCHAT_APPCONTAINER=1) instead of on by default, to avoid extra launcher processes and heavy startup until the path is stable.
## [4.8.0] - 2026-07-25

diff --git a/docs/agents/skills/electron-frozen-packaging/SKILL.md b/docs/agents/skills/electron-frozen-packaging/SKILL.md
index b1c87989..0b35b31b 100644
--- a/docs/agents/skills/electron-frozen-packaging/SKILL.md
+++ b/docs/agents/skills/electron-frozen-packaging/SKILL.md
@@ -13,7 +13,7 @@ Package and recover the desktop shell correctly: frozen subprocess re-entry, loa
- In frozen builds, `sys.executable` **is** MeshChatX.
- Never spawn `python -m …` or `python -c …` for bots, rnsh, LXMFy, or self-check probes from the packaged app.
- Use `--meshchatx-run-module <module>` so helpers re-enter the same binary without launching a second full app (storage lock collision).
-- On Windows, Electron starts the long-lived backend through `--meshchatx-run-module meshchatx.src.backend.appcontainer_launcher` unless `MESHCHAT_APPCONTAINER=0`. The launcher CreateProcess-es the real backend into an LPAC AppContainer. Orphan kill must use process-tree termination (`taskkill /T`) so both launcher and child exit.
+- On Windows, Electron can start the backend through `--meshchatx-run-module meshchatx.src.backend.appcontainer_launcher` when `MESHCHAT_APPCONTAINER=1`. The launcher CreateProcess-es the real backend into an LPAC AppContainer. Orphan kill must use process-tree termination (`taskkill /T`) so both launcher and child exit. Default is off (direct backend spawn).
## Loading and navigation

diff --git a/docs/agents/skills/landlock-sqlite/SKILL.md b/docs/agents/skills/landlock-sqlite/SKILL.md
index c3a5bc99..35cc50ff 100644
--- a/docs/agents/skills/landlock-sqlite/SKILL.md
+++ b/docs/agents/skills/landlock-sqlite/SKILL.md
@@ -29,7 +29,7 @@ Landlock / Windows AppContainer + SQLite conversation-load failures (temp_store,
- Module: `meshchatx/src/backend/appcontainer_sandbox.py`
- Launcher: `meshchatx/src/backend/appcontainer_launcher.py` via `--meshchatx-run-module`
-- Electron win32 spawn uses the launcher unless `MESHCHAT_APPCONTAINER=0`
+- Electron win32 spawn uses the launcher only when `MESHCHAT_APPCONTAINER=1`
- Docs: `meshchatx-docs/en/platform-guides/windows-sandbox.md`
## Verification

diff --git a/electron/backendProcess.js b/electron/backendProcess.js
index 84a8b988..b61d1b3b 100644
--- a/electron/backendProcess.js
+++ b/electron/backendProcess.js
@@ -208,8 +208,8 @@ function createBackendProcessManager(deps) {
return true;
}
}
- // Default on for Windows desktop shells (Landlock equivalent).
- return true;
+ // Opt-in only: set MESHCHAT_APPCONTAINER=1 to use the AppContainer launcher.
+ return false;
}
function buildSpawnArgs(extraArgs = []) {

diff --git a/meshchatx.rsm b/meshchatx.rsm
index 521a6744..15fbd3df 100644
Binary files a/meshchatx.rsm and b/meshchatx.rsm differ

diff --git a/meshchatx/src/backend/appcontainer_sandbox.py b/meshchatx/src/backend/appcontainer_sandbox.py
index e40b9fdc..cab03c40 100644
--- a/meshchatx/src/backend/appcontainer_sandbox.py
+++ b/meshchatx/src/backend/appcontainer_sandbox.py
@@ -248,7 +248,7 @@ def appcontainer_requested() -> bool:
return False
if override is True:
return True
- return appcontainer_supported()
+ return False
def appcontainer_auto_enabled() -> bool:

diff --git a/tests/backend/test_appcontainer_sandbox.py b/tests/backend/test_appcontainer_sandbox.py
index ede7f931..3d67d5a1 100644
--- a/tests/backend/test_appcontainer_sandbox.py
+++ b/tests/backend/test_appcontainer_sandbox.py
@@ -44,15 +44,15 @@ def test_appcontainer_forced_env(monkeypatch):
assert ac.appcontainer_forced() is True
-def test_appcontainer_auto_when_supported(monkeypatch):
+def test_appcontainer_off_by_default_when_env_unset(monkeypatch):
monkeypatch.delenv("MESHCHAT_APPCONTAINER", raising=False)
with (
patch.object(ac, "sys") as mock_sys,
patch.object(ac, "appcontainer_supported", return_value=True),
):
mock_sys.platform = "win32"
- assert ac.appcontainer_requested() is True
- assert ac.appcontainer_auto_enabled() is True
+ assert ac.appcontainer_requested() is False
+ assert ac.appcontainer_auto_enabled() is False
def test_is_appcontainer_child(monkeypatch):

diff --git a/tests/electron/backendProcess.test.js b/tests/electron/backendProcess.test.js
index 3902b880..26269595 100644
--- a/tests/electron/backendProcess.test.js
+++ b/tests/electron/backendProcess.test.js
@@ -99,10 +99,38 @@ describe("electron/backendProcess", () => {
expect(showCrashPage).toHaveBeenCalledWith(expect.objectContaining({ code: 1 }));
});
- it("wraps win32 spawn through the AppContainer launcher by default", async () => {
+ it("does not use AppContainer launcher on win32 by default", async () => {
const previousPlatform = process.platform;
Object.defineProperty(process, "platform", { value: "win32" });
delete process.env.MESHCHAT_APPCONTAINER;
+ try {
+ const manager = createBackendProcessManager({
+ log: vi.fn(),
+ getDefaultStorageDir: () => "C:\\Users\\test\\.reticulum-meshchatx",
+ getDefaultReticulumConfigDir: () => "C:\\Users\\test\\.reticulum",
+ getMainWindowPageKind: () => "loading",
+ isQuiting: () => false,
+ notifyRenderer: vi.fn(),
+ showCrashPage: vi.fn(),
+ spawn: spawnMock,
+ });
+ manager.setUserProvidedArguments([]);
+ await manager.spawnBackend("C:\\App\\ReticulumMeshChatX.exe", {
+ backend: { ok: true, issues: [] },
+ });
+ const args = spawnMock.mock.calls[0][1];
+ expect(args).not.toContain("--meshchatx-run-module");
+ expect(args[0]).toBe("--headless");
+ } finally {
+ Object.defineProperty(process, "platform", { value: previousPlatform });
+ }
+ });
+
+ it("wraps win32 spawn through the AppContainer launcher when MESHCHAT_APPCONTAINER=1", async () => {
+ const previousPlatform = process.platform;
+ const previousEnv = process.env.MESHCHAT_APPCONTAINER;
+ Object.defineProperty(process, "platform", { value: "win32" });
+ process.env.MESHCHAT_APPCONTAINER = "1";
try {
const manager = createBackendProcessManager({
log: vi.fn(),
@@ -131,6 +159,11 @@ describe("electron/backendProcess", () => {
);
} finally {
Object.defineProperty(process, "platform", { value: previousPlatform });
+ if (previousEnv === undefined) {
+ delete process.env.MESHCHAT_APPCONTAINER;
+ } else {
+ process.env.MESHCHAT_APPCONTAINER = previousEnv;
+ }
}
});


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────